<template>
  <div class="wg-cap-wrap">
    <div class="wg-cap-wrap__header">
      <span
        >{{ $t('loginPage.captchaTips')
        }}<em>{{ $t('loginPage.captchaInOrder') }}</em></span
      >
      <img
        v-if="thumbBase64Code"
        class="wg-cap-wrap__thumb"
        :src="thumbBase64Code"
        alt=" "
      />
    </div>
    <div class="wg-cap-wrap__body" :style="style">
      <img
        v-if="imageBase64Code"
        class="wg-cap-wrap__picture"
        :src="imageBase64Code"
        alt=" "
        @click="handleClickPos($event)"
      />
      <img
        class="wg-cap-wrap__loading"
        src=""
        alt="正在加载中..."
      />
      <div v-for="(dot, key) in dots" :key="key">
        <div
          class="wg-cap-wrap__dot"
          :style="`top: ${dot.y}px; left:${dot.x}px;`"
        >
          <span>{{ dot.index }}</span>
        </div>
      </div>
    </div>
    <div class="wg-cap-wrap__footer">
      <div class="wg-cap-wrap__ico">
        <img
          src=""
          alt="关闭"
          @click="handleCloseEvent"
        />
        <img
          src=""
          alt="刷新"
          @click="handleRefreshEvent"
        />
      </div>
      <div class="wg-cap-wrap__btn">
        <button @click="handleConfirmEvent">{{ $t('confirm') }}</button>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { computed, watch, ref } from 'vue'
const props = defineProps({
  modelValue: Boolean,
  width: {
    type: String,
    default: '',
  },
  height: {
    type: String,
    default: '',
  },
  calcPosType: {
    type: String,
    default: 'dom',
    validator: (value: string) => ['dom', 'screen'].includes(value),
  },
  maxDot: {
    type: Number,
    default: 5,
  },
  imageBase64: {
    type: String,
    default: '',
  },
  thumbBase64: {
    type: String,
    default: '',
  },
})
const dots = ref<{ x: number; y: number; index: number }[]>([])
const imageBase64Code = ref('')
const thumbBase64Code = ref('')
watch(
  () => {
    return props.modelValue
  },
  () => {
    dots.value = []
    imageBase64Code.value = ''
    thumbBase64Code.value = ''
  }
)
watch(
  () => {
    return props.imageBase64
  },
  (val: string) => {
    dots.value = []
    imageBase64Code.value = val
  }
)
watch(
  () => {
    return props.thumbBase64
  },
  (val: string) => {
    dots.value = []
    thumbBase64Code.value = val
  }
)
const style = computed(() => {
  return `width:${props.width}; height:${props.height};`
})

const emit = defineEmits(['close', 'refresh', 'confirm'])
/**
 * @Description: 处理关闭事件
 */
function handleCloseEvent() {
  emit('close')
  dots.value = []
  imageBase64Code.value = ''
  thumbBase64Code.value = ''
}
/**
 * @Description: 处理刷新事件
 */
function handleRefreshEvent() {
  dots.value = []
  emit('refresh')
}
/**
 * @Description: 处理确认事件
 */
function handleConfirmEvent() {
  emit('confirm', dots.value)
}
/**
 * @Description: 处理dot
 * @param ev
 */
function handleClickPos(ev: any) {
  if (dots.value.length >= props.maxDot) {
    return
  }
  const e = ev || window.event
  e.preventDefault()
  const dom = e.currentTarget

  const { domX, domY } = getDomXY(dom)
  // ===============================================
  // @notice 如 getDomXY 不准确可尝试使用 calcLocationLeft 或 calcLocationTop
  // const domX = calcLocationLeft(dom)
  // const domY = calcLocationTop(dom)
  // ===============================================

  let mouseX =
    navigator.appName === 'Netscape' ? e.pageX : e.x + document.body.offsetTop
  let mouseY =
    navigator.appName === 'Netscape' ? e.pageY : e.y + document.body.offsetTop

  if (props.calcPosType === 'screen') {
    mouseX = navigator.appName === 'Netscape' ? e.clientX : e.x
    mouseY = navigator.appName === 'Netscape' ? e.clientY : e.y
  }

  // 计算点击的相对位置
  const xPos = mouseX - domX
  const yPos = mouseY - domY

  // 转整形
  const xp = parseInt(xPos.toString())
  const yp = parseInt(yPos.toString())

  // 减去点的一半
  dots.value.push({
    x: xp - 11,
    y: yp - 11,
    index: dots.value.length + 1,
  })
  return false
}
/**
 * @Description: 找到元素的屏幕位置
 * @param dom
 */
function getDomXY(dom: any) {
  let x = 0
  let y = 0
  if (dom.getBoundingClientRect) {
    let box = dom.getBoundingClientRect()
    let D = document.documentElement
    x =
      box.left + Math.max(D.scrollLeft, document.body.scrollLeft) - D.clientLeft
    y = box.top + Math.max(D.scrollTop, document.body.scrollTop) - D.clientTop
  } else {
    while (dom !== document.body) {
      x += dom.offsetLeft
      y += dom.offsetTop
      dom = dom.offsetParent
    }
  }
  return {
    domX: x,
    domY: y,
  }
}
</script>

<style>
.wg-cap-wrap {
  width: 100%;
  height: 100%;
  background: #ffffff;

  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  border-radius: 10px;

  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
.wg-cap-wrap__header {
  height: 50px;
  width: 100%;
  font-size: 15px;

  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
  -webkit-align-items: center;
  -ms-flex-align: center;
  align-items: center;
}
.wg-cap-wrap__header span {
  padding-right: 5px;
}
.wg-cap-wrap__header span em {
  padding: 0 3px;
  font-weight: bold;
  color: #3e7cff;
  font-style: normal;
}
.wg-cap-wrap__header .wg-cap-wrap__image {
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border-radius: 5px;
  overflow: hidden;
  text-align: center;
  line-height: 1;
}
.wg-cap-wrap__header .wg-cap-wrap__thumb {
  min-width: 150px;
  text-align: center;
  line-height: 1;
  max-height: 100%;
}
.wg-cap-wrap__header .wg-cap-wrap__thumb.wg-cap-wrap__hidden {
  display: none;
}

.wg-cap-wrap__body {
  position: relative;
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  background: #34383e;
  margin: auto;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border-radius: 5px;
  overflow: hidden;
}
.wg-cap-wrap__body .wg-cap-wrap__picture {
  position: relative;
  z-index: 10;
  width: 100%;

  /*height: 100%;*/
  /*max-width: 100%;*/
  /*max-height: 100%;*/
  /*object-fit: cover;*/
  /*text-align: center;*/
}
.wg-cap-wrap__body .wg-cap-wrap__picture.wg-cap-wrap__hidden {
  display: none;
}
.wg-cap-wrap__body .wg-cap-wrap__loading {
  position: absolute;
  z-index: 9;
  top: 50%;
  left: 50%;
  width: 68px;
  height: 68px;
  margin-left: -34px;
  margin-top: -34px;
  line-height: 68px;
  text-align: center;
}
.wg-cap-wrap__body .wg-cap-wrap__dot {
  position: absolute;
  z-index: 10;
  width: 22px;
  height: 22px;
  color: #cedffe;
  background: #3e7cff;
  border: 2px solid #f7f9fb;
  line-height: 20px;
  text-align: center;
  -webkit-border-radius: 22px;
  -moz-border-radius: 22px;
  border-radius: 22px;
  cursor: default;
}

.wg-cap-wrap__footer {
  width: 100%;
  height: 40px;
  color: #34383e;
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
  -webkit-align-items: center;
  -ms-flex-align: center;
  align-items: center;
  padding-top: 15px;
}
.wg-cap-wrap__footer .wg-cap-wrap__ico {
  flex: 1;
}
.wg-cap-wrap__footer .wg-cap-wrap__ico img {
  width: 24px;
  height: 24px;
  color: #34383e;
  margin: 0 5px;
  cursor: pointer;
}
.wg-cap-wrap__footer .wg-cap-wrap__btn {
  width: 120px;
  height: 40px;
}
.wg-cap-wrap__footer .wg-cap-wrap__btn button {
  width: 100%;
  height: 40px;
  letter-spacing: 2px;
  text-align: center;
  padding: 9px 15px;
  font-size: 15px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border-radius: 5px;
  display: inline-block;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  color: #fff;
  background-color: #409eff;
  border: 1px solid #409eff;
  -webkit-appearance: none;
  box-sizing: border-box;
  outline: none;
  margin: 0;
  transition: 0.1s;
  font-weight: 500;
  -moz-user-select: none;
  -webkit-user-select: none;
}
.wg-cap-wrap__footer .wg-cap-wrap__btn button:hover {
  background: #66b1ff;
  border-color: #66b1ff;
  color: #fff;
}
</style>
